package com.sweet.multipledatasources.api;

import com.sweet.multipledatasources.MainVerticle;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Promise;
import io.vertx.core.eventbus.ReplyException;
import io.vertx.core.impl.logging.Logger;
import io.vertx.core.impl.logging.LoggerFactory;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.handler.BodyHandler;

public class ApiVerticle extends AbstractVerticle {

  private final Logger logger = LoggerFactory.getLogger(MainVerticle.class);

  @Override
  public void start(Promise<Void> startPromise) throws Exception {
    JsonObject config = config();
    Integer port = config.getInteger("port");
    Router router = Router.router(vertx);
    router.route().handler(BodyHandler.create())
            .failureHandler(ctx -> {
              String path = ctx.request().path();
              Throwable failure = ctx.failure();
              logger.error("failureHandlerErr:path:" + path, failure);
              fail(ctx, "未知错误");
            });

    router.post("/app/query")
            .handler(ctx -> {
              JsonObject reqBody = ctx.body().asJsonObject();
              logger.debug("/app/query Body:" + reqBody);
              String name = reqBody.getString("name");
              vertx.eventBus().<JsonObject>request(name, reqBody).onFailure(fail -> {
                if (fail instanceof ReplyException) {
                  ReplyException replyException = (ReplyException) fail;
                  fail(ctx, replyException.failureCode(), replyException.getMessage());
                  return;
                }
                logger.error("eventBusFail", fail);
                fail(ctx, fail.getMessage());
              }).onSuccess(res -> {
                JsonObject body = res.body();
                ok(ctx, body);
              });
            });

    vertx.createHttpServer().requestHandler(router).listen(port, http -> {
      if (http.succeeded()) {
        logger.debug("http Started：" + port);
        startPromise.complete();
      } else {
        startPromise.fail(http.cause());
      }
    });
  }

  private void ok(RoutingContext ctx, JsonObject obj) {
    ctx.json(new JsonObject().put("code", 0).put("data", obj));
  }

  private void fail(RoutingContext ctx, String msg) {
    fail(ctx, 1, msg);
  }

  private void fail(RoutingContext ctx, int code, String msg) {
    ctx.json(new JsonObject().put("code", code).put("msg", msg));
  }

  @Override
  public void stop() throws Exception {
    logger.debug("apiServiceStop");
    super.stop();
  }
}
